package cn.anoxia.springframework.beans.support;

import cn.anoxia.springframework.beans.BeansException;
import cn.anoxia.springframework.beans.factory.BeanDefinition;
import cn.anoxia.springframework.beans.factory.DisposableBean;
import cn.hutool.core.util.StrUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * The class DisposableBeanAdapter.
 * <p>
 * Description:
 *
 * @author: huangle
 * @since: 2021/08/27 10:39
 * ${tags}
 * @version: ${Revision} ${date} ${LastChangedBy}
 */
public class DisposableBeanAdapter implements DisposableBean {

  private final Object bean;
  private final String beanName;
  private String destroyMethodName;

  public DisposableBeanAdapter(Object bean, String beanName, BeanDefinition beanDefinition) {
    this.bean = bean;
    this.beanName = beanName;
    this.destroyMethodName = beanDefinition.getDestroyMethodName();
  }

  @Override
  public void destroy() throws BeansException, InvocationTargetException, IllegalAccessException, NoSuchMethodException {
    if (bean instanceof DisposableBean){
      ((DisposableBean) bean).destroy();
    }

    if (StrUtil.isNotBlank(destroyMethodName) && !(bean instanceof DisposableBean
     && "destroy".equals(this.destroyMethodName))){
      Method method = bean.getClass().getMethod(destroyMethodName);
      if (method == null){
        throw new BeansException("Couldn't find a 销毁 method named '" + destroyMethodName + "' on bean with name '" + beanName + "'");
      }
      method.invoke(bean);
    }
  }

  public Object getBean() {
    return bean;
  }

  public String getBeanName() {
    return beanName;
  }

  public String getDestroyMethodName() {
    return destroyMethodName;
  }

  public void setDestroyMethodName(String destroyMethodName) {
    this.destroyMethodName = destroyMethodName;
  }
}
